/**
 * Bilibili下载器 - 弹出页面脚本
 * 
 * 负责处理以下功能：
 * 1. 从当前标签页获取视频信息
 * 2. 显示视频下载选项
 * 3. 处理用户下载请求
 * 4. 显示下载进度和历史记录
 */

// DOM元素引用
/** @type {Object} 页面DOM元素引用 */
let elements = {};

// 全局变量
/** @type {Object|null} 当前视频信息 */
let currentVideoInfo = null;
/** @type {boolean} 是否正在查询视频信息 */
let isQueryingInfo = false;
/** @type {Object} 用户设置 */
let userSettings = {
  format: 'mp4',
  quality: '720',
  downloadPath: ''
};
/** @type {number|null} 进度更新定时器ID */
let progressUpdateInterval = null;

// 初始化
document.addEventListener('DOMContentLoaded', () => {
  // 初始化DOM引用
  initDOMReferences();
  
  // 绑定事件监听器
  bindEventListeners();
  
  // 获取用户设置
  loadUserSettings();
  
  // 获取下载历史
  loadDownloadHistory();
  
  // 尝试从本地存储获取最近的视频信息
  chrome.storage.local.get({ recentVideoInfo: null }, (data) => {
    if (data.recentVideoInfo) {
      // 如果存在存储的视频信息，直接使用
      currentVideoInfo = data.recentVideoInfo;
      updateVideoInfoUI(currentVideoInfo);
      updateUIState('ready');
    } else {
      // 否则从当前标签页获取信息
      getCurrentTabInfo();
    }
  });
});

/**
 * 初始化DOM元素引用
 */
function initDOMReferences() {
  elements = {
    videoInfo: document.getElementById('videoInfo'),
    loading: document.getElementById('loading'),
    videoDetails: document.querySelector('.video-details'),
    videoCover: document.getElementById('videoCover'),
    videoTitle: document.getElementById('videoTitle'),
    videoUploader: document.getElementById('videoUploader'),
    
    downloadOptions: document.getElementById('downloadOptions'),
    formatSelect: document.getElementById('formatSelect'),
    qualitySelect: document.getElementById('qualitySelect'),
    downloadPath: document.getElementById('downloadPath'),
    choosePathBtn: document.getElementById('choosePathBtn'),
    downloadBtn: document.getElementById('downloadBtn'),
    
    downloadProgress: document.getElementById('downloadProgress'),
    progressBar: document.getElementById('progressBar'),
    progressPercent: document.getElementById('progressPercent'),
    downloadSpeed: document.getElementById('downloadSpeed'),
    timeRemaining: document.getElementById('timeRemaining'),
    cancelBtn: document.getElementById('cancelBtn'),
    
    emptyDownloadList: document.getElementById('emptyDownloadList'),
    downloadList: document.getElementById('downloadList'),
    
    settingsBtn: document.getElementById('settingsBtn'),
    helpBtn: document.getElementById('helpBtn')
  };
}

/**
 * 绑定事件监听器
 */
function bindEventListeners() {
  // 下载按钮
  elements.downloadBtn.addEventListener('click', handleDownloadClick);
  
  // 取消下载按钮
  elements.cancelBtn.addEventListener('click', handleCancelDownload);
  
  // 选择下载路径按钮
  elements.choosePathBtn.addEventListener('click', handleChoosePath);
  
  // 设置按钮
  elements.settingsBtn.addEventListener('click', handleSettings);
  
  // 帮助按钮
  elements.helpBtn.addEventListener('click', handleHelp);
  
  // 下载格式变更
  elements.formatSelect.addEventListener('change', handleFormatChange);
}

/**
 * 加载用户设置
 */
function loadUserSettings() {
  chrome.storage.local.get({
    defaultFormat: 'mp4',
    defaultQuality: '720',
    customDownloadPath: ''
  }, (settings) => {
    userSettings.format = settings.defaultFormat;
    userSettings.quality = settings.defaultQuality;
    userSettings.downloadPath = settings.customDownloadPath;
    
    // 更新界面
    elements.formatSelect.value = userSettings.format;
    elements.qualitySelect.value = userSettings.quality;
    
    if (userSettings.downloadPath) {
      elements.downloadPath.textContent = userSettings.downloadPath;
    }
  });
}

/**
 * 加载下载历史记录
 */
function loadDownloadHistory() {
  chrome.storage.local.get({ downloadHistory: [] }, (data) => {
    updateDownloadHistoryUI(data.downloadHistory);
  });
}

/**
 * 更新下载历史UI
 * @param {Array} history - 下载历史记录
 */
function updateDownloadHistoryUI(history) {
  elements.downloadList.innerHTML = '';
  
  if (history.length === 0) {
    elements.emptyDownloadList.style.display = 'block';
    return;
  }
  
  elements.emptyDownloadList.style.display = 'none';
  
  // 显示最近的5条记录
  const recentHistory = history.slice(0, 5);
  
  recentHistory.forEach(item => {
    const li = document.createElement('li');
    
    // 格式化时间
    const date = new Date(item.time);
    const timeStr = `${date.getMonth() + 1}/${date.getDate()} ${date.getHours()}:${String(date.getMinutes()).padStart(2, '0')}`;
    
    // 设置状态颜色
    let statusColor = '#666';
    let statusText = '未知';
    
    switch (item.status) {
      case 'completed':
        statusColor = '#4CAF50';
        statusText = '完成';
        break;
      case 'error':
        statusColor = '#F44336';
        statusText = '失败';
        break;
      case 'downloading':
        statusColor = '#2196F3';
        statusText = '下载中';
        break;
      case 'queued':
        statusColor = '#FF9800';
        statusText = '队列中';
        break;
    }
    
    li.innerHTML = `
      <div class="download-item-title">${item.title}</div>
      <div class="download-item-info">
        <span style="color: ${statusColor}">${statusText}</span>
        <span>${timeStr}</span>
      </div>
    `;
    
    elements.downloadList.appendChild(li);
  });
}

/**
 * 获取当前标签页信息
 */
function getCurrentTabInfo() {
  isQueryingInfo = true;
  updateUIState('loading');
  
  chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
    const currentTab = tabs[0];
    
    // 检查是否在Bilibili视频页面
    if (currentTab.url.includes('bilibili.com/video/')) {
      // 向内容脚本发送消息获取视频信息
      chrome.tabs.sendMessage(currentTab.id, { action: 'getVideoInfo' }, (response) => {
        isQueryingInfo = false;
        
        if (chrome.runtime.lastError) {
          // 可能内容脚本未加载
          console.error('与内容脚本通信失败:', chrome.runtime.lastError);
          updateUIState('error');
          return;
        }
        
        if (response && response.success && response.videoInfo) {
          // 保存视频信息
          currentVideoInfo = response.videoInfo;
          // 保存到存储中，便于下次使用
          chrome.storage.local.set({ recentVideoInfo: currentVideoInfo });
          // 更新UI
          updateVideoInfoUI(currentVideoInfo);
          updateUIState('ready');
        } else {
          updateUIState('error');
        }
      });
    } else {
      // 不在视频页面
      isQueryingInfo = false;
      updateUIState('not_video_page');
    }
  });
}

/**
 * 更新视频信息UI
 * @param {Object} videoInfo - 视频信息
 */
function updateVideoInfoUI(videoInfo) {
  elements.videoTitle.textContent = videoInfo.title;
  elements.videoUploader.textContent = videoInfo.uploader || '未知上传者';
  
  if (videoInfo.cover) {
    elements.videoCover.src = videoInfo.cover;
  }
}

/**
 * 更新UI状态
 * @param {string} state - UI状态
 */
function updateUIState(state) {
  switch (state) {
    case 'loading':
      elements.loading.style.display = 'block';
      elements.videoDetails.style.display = 'none';
      elements.downloadOptions.style.display = 'none';
      elements.downloadProgress.style.display = 'none';
      elements.loading.innerHTML = '<p>正在获取视频信息...</p>';
      break;
      
    case 'ready':
      elements.loading.style.display = 'none';
      elements.videoDetails.style.display = 'flex';
      elements.downloadOptions.style.display = 'block';
      elements.downloadProgress.style.display = 'none';
      break;
      
    case 'error':
      elements.loading.style.display = 'block';
      elements.videoDetails.style.display = 'none';
      elements.downloadOptions.style.display = 'none';
      elements.downloadProgress.style.display = 'none';
      elements.loading.innerHTML = '<p>获取视频信息失败，请刷新页面后重试</p>';
      break;
      
    case 'not_video_page':
      elements.loading.style.display = 'block';
      elements.videoDetails.style.display = 'none';
      elements.downloadOptions.style.display = 'none';
      elements.downloadProgress.style.display = 'none';
      elements.loading.innerHTML = '<p>请在Bilibili视频页面使用此扩展</p>';
      break;
      
    case 'downloading':
      elements.downloadOptions.style.display = 'none';
      elements.downloadProgress.style.display = 'block';
      startProgressUpdates();
      break;
  }
}

/**
 * 处理下载按钮点击
 */
function handleDownloadClick() {
  if (!currentVideoInfo) {
    alert('未找到可下载的视频信息');
    return;
  }
  
  // 获取下载选项
  const options = {
    format: elements.formatSelect.value,
    quality: elements.qualitySelect.value,
    downloadPath: userSettings.downloadPath
  };
  
  // 更新UI状态
  updateUIState('downloading');
  
  // 发送下载请求
  chrome.runtime.sendMessage({
    action: 'startDownload',
    videoInfo: currentVideoInfo,
    options: options
  }, (response) => {
    if (chrome.runtime.lastError || !response || !response.success) {
      console.error('启动下载失败:', chrome.runtime.lastError);
      updateUIState('error');
    } else {
      // 保存用户设置
      saveUserSettings(options);
    }
  });
}

/**
 * 处理取消下载
 */
function handleCancelDownload() {
  // 发送取消下载请求
  chrome.runtime.sendMessage({ action: 'cancelDownload' }, (response) => {
    if (response && response.success) {
      updateUIState('ready');
      stopProgressUpdates();
    }
  });
}

/**
 * 处理选择下载路径
 */
function handleChoosePath() {
  // 实际上，由于浏览器扩展的安全限制，无法直接选择目录
  // 我们可以提供预设选项或让用户输入路径
  // 这里用一个简单的prompt模拟
  const path = prompt('请输入下载路径（相对于浏览器默认下载目录）:', userSettings.downloadPath);
  
  if (path !== null) {
    userSettings.downloadPath = path;
    elements.downloadPath.textContent = path || '使用浏览器默认下载路径';
    
    // 保存设置
    chrome.storage.local.set({ customDownloadPath: path });
  }
}

/**
 * 处理设置按钮点击
 */
function handleSettings() {
  // 这里可以打开设置页面或显示设置弹窗
  alert('设置功能将在后续版本中提供');
}

/**
 * 处理帮助按钮点击
 */
function handleHelp() {
  // 打开帮助页面
  chrome.tabs.create({ url: 'https://github.com/YourUsername/bilibili-downloader' });
}

/**
 * 处理格式变更
 */
function handleFormatChange() {
  const format = elements.formatSelect.value;
  
  // 如果选择了MP3，不需要显示质量选择
  elements.qualitySelect.disabled = (format === 'mp3');
}

/**
 * 保存用户设置
 * @param {Object} options - 用户选项
 */
function saveUserSettings(options) {
  chrome.runtime.sendMessage({
    action: 'saveSettings',
    settings: {
      format: options.format,
      quality: options.quality,
      downloadPath: options.downloadPath
    }
  });
}

/**
 * 开始更新进度
 */
function startProgressUpdates() {
  // 先立即更新一次
  updateDownloadProgress();
  
  // 每秒更新一次进度
  progressUpdateInterval = setInterval(updateDownloadProgress, 1000);
}

/**
 * 停止更新进度
 */
function stopProgressUpdates() {
  if (progressUpdateInterval) {
    clearInterval(progressUpdateInterval);
    progressUpdateInterval = null;
  }
}

/**
 * 更新下载进度
 */
function updateDownloadProgress() {
  chrome.runtime.sendMessage({ action: 'getDownloadProgress' }, (response) => {
    if (!response || !response.isDownloading) {
      // 下载已完成或已取消
      updateUIState('ready');
      stopProgressUpdates();
      loadDownloadHistory(); // 刷新下载历史
      return;
    }
    
    // 更新进度条
    const progress = response.downloadStatus.progress;
    elements.progressBar.style.width = `${progress}%`;
    elements.progressPercent.textContent = `${progress}%`;
    
    // 更新下载速度
    const speed = formatSpeed(response.downloadStatus.speed);
    elements.downloadSpeed.textContent = speed;
    
    // 更新剩余时间
    const timeRemaining = formatTime(response.downloadStatus.timeRemaining);
    elements.timeRemaining.textContent = `剩余时间: ${timeRemaining}`;
  });
}

/**
 * 格式化下载速度
 * @param {number} bytesPerSecond - 每秒字节数
 * @returns {string} 格式化后的速度
 */
function formatSpeed(bytesPerSecond) {
  if (bytesPerSecond === 0) return '0 KB/s';
  
  if (bytesPerSecond < 1024) {
    return `${bytesPerSecond.toFixed(1)} B/s`;
  } else if (bytesPerSecond < 1024 * 1024) {
    return `${(bytesPerSecond / 1024).toFixed(1)} KB/s`;
  } else {
    return `${(bytesPerSecond / (1024 * 1024)).toFixed(1)} MB/s`;
  }
}

/**
 * 格式化时间
 * @param {number} seconds - 秒数
 * @returns {string} 格式化后的时间
 */
function formatTime(seconds) {
  if (!seconds || seconds === 0) return '计算中...';
  
  if (seconds < 60) {
    return `${Math.ceil(seconds)} 秒`;
  } else if (seconds < 3600) {
    const minutes = Math.floor(seconds / 60);
    const secs = Math.ceil(seconds % 60);
    return `${minutes} 分 ${secs} 秒`;
  } else {
    const hours = Math.floor(seconds / 3600);
    const minutes = Math.floor((seconds % 3600) / 60);
    return `${hours} 时 ${minutes} 分`;
  }
} 